
#include <cstdio>
#include <BPainter>
#include <BMouseEvent>

#include "SvgGraphicItem.h"

SvgGraphicItem::SvgGraphicItem(BGraphicItem* parent) : BGraphicItem(parent)
{
	_dirty = false;
}
SvgGraphicItem::~SvgGraphicItem()
{

}

void SvgGraphicItem::appendPoint(const BPointf& point)
{
	_points.append(point);
	_dirty = true;
	this->fresh();
}
void SvgGraphicItem::insertPoint(int index, const BPointf& point)
{
	_points.insert(index, point);
	_dirty = true;
	this->fresh();
}
void SvgGraphicItem::removePoint(int index)
{
	_points.remove(index);
	_dirty = true;
	this->fresh();
}
void SvgGraphicItem::clearPoints()
{
	_points.clear();
	_indices.clear();
	_dirty = true;
	this->fresh();
}

int SvgGraphicItem::pointCount() const
{
	return _points.size();
}
const BPointf& SvgGraphicItem::point(int index) const
{
	return _points(index);
}

bool SvgGraphicItem::stepFill()
{
	if (_indices.size() == 3)
	{
		_trig_indices.append(_indices);
		_indices.clear();
		return true;
	}
	if (_indices.size() > 3)
	{
		int min_pos = -1;
		BReal min_angle = REAL_MAX;
		for (int i = 0; i < _indices.size(); i++)
		{
			BReal angle = _angles[i];
			if (min_angle > angle)
			{
				min_angle = angle;
				min_pos = i;
			}
		}
		int prev_index = (min_pos == 0) ? _indices.last() : _indices[min_pos - 1];
		int curr_index = _indices[min_pos];
		int next_index = (min_pos == _indices.size() - 1) ? _indices.first() : _indices[min_pos + 1];
		_trig_indices.append(prev_index);
		_trig_indices.append(curr_index);
		_trig_indices.append(next_index);
		_indices.remove(min_pos, 1);
		_angles.remove(min_pos);
		if (min_pos == _indices.size())
			min_pos = _indices.size() - 1;
		freshAngle(min_pos, _indices, _angles);
		int prev_pos = (min_pos == 0) ? _indices.size() - 1 : min_pos - 1;
		freshAngle(prev_pos, _indices, _angles);
		return true;
	}
	return false;
}

void SvgGraphicItem::freshAngle(int pos, BIntArray& indices, BRealArray& angles) const
{
	int prev_index = (pos == 0) ? indices.last() : indices[pos - 1];
	int curr_index = indices[pos];
	int next_index = (pos == indices.size() - 1) ? indices.first() : indices[pos + 1];
	BPointf prev = _points[prev_index];
	BPointf curr = _points[curr_index];
	BPointf next = _points[next_index];
	BPointf vec0 = (prev - curr).normal();
	BPointf vec1 = (next - curr).normal();
	float angle = vec0.angle(vec1);
	if (vec0.cross(vec1) < 0)
		angle = PI2f - angle;
	angles[pos] = bRTD(angle);
}

void SvgGraphicItem::paint(BPainter& painter)
{
	BGraphicItem::paint(painter);
	painter.setColor(Color_Line);
	painter.drawPolygon(_points);

	for (int i = 0; i < _trig_indices.size(); i += 3)
	{
		int ia = _trig_indices[i];
		int ib = _trig_indices[i + 1];
		int ic = _trig_indices[i + 2];
		painter.setColor(200, 0, 0);
		painter.fillTriangle(_points[ia], _points[ib], _points[ic]);
		int a = 0;
	}
	BPointfArray points;
	for (int i = 0; i < _indices.size(); i++)
	{
		int index = _indices[i];
		const BPointf& pos = _points[index];
		points.append(pos);
		//BReal angle = _angles[i];
		//painter.setColor(Color_Text);
		//painter.drawText(pos, (int)angle);
	}
	painter.setColor(0, 200, 0);
	painter.setLineStipple(0xf0f0);
	painter.drawPolygon(points);
}

void SvgGraphicItem::freshEvent(const BEvent& event)
{
	if (_dirty)
	{
		if (_points.size() == 5)
			int a = 0;
		_trig_indices.reset();
		if (_points.size() >= 3)
		{
			_angles.resize(_points.size());
			_indices.resize(_points.size());
			for (int i = 0; i < _points.size(); i++)
				_indices[i] = i;
			for (int i = 0; i < _indices.size(); i++)
				freshAngle(i, _indices, _angles);
			for (int i = 0; i < _points.size() - 1; i++)
				_center += _points[i];
			_center += _points.last();
			_center /= _points.size();
		}
		_dirty = true;
	}
}

void SvgGraphicItem::mouseMoveEvent(const BMouseEvent& mouseEvent)
{

}
void SvgGraphicItem::mouseClickEvent(const BMouseEvent& mouseEvent)
{
	const BPointf pos = mouseEvent.pos();
	_points.append(pos);
	_dirty = true;
	this->fresh();
}
